package com.atguigu.consumer;

import com.atguigu.constant.MqConst;
import com.atguigu.constant.RedisConst;
import com.atguigu.entity.SeckillProduct;
import com.atguigu.entity.UserSeckillSkuInfo;
import com.atguigu.service.SeckillProductService;
import com.atguigu.utils.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.rabbitmq.client.Channel;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.Exchange;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.QueueBinding;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.cache.CacheProperties;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import java.io.IOException;
import java.util.Date;
import java.util.List;

@Component
public class seckillConsumer {
@Autowired
    SeckillProductService seckillProductService;
@Autowired
    RedisTemplate redisTemplate;
    @RabbitListener(bindings = @QueueBinding(
            value = @Queue(value = MqConst.SCAN_SECKILL_QUEUE,durable = "false"),
            exchange = @Exchange(value = MqConst.SCAN_SECKILL_EXCHANGE,durable = "false",autoDelete = "true"),
            key = {MqConst.SCAN_SECKILL_ROUTE_KEY}))
    public void scanSeckillProductToRedis(Message message, Channel channel) throws Exception{
            //描述符合秒杀条件的商品
        QueryWrapper<SeckillProduct> wrapper = new QueryWrapper<>();
        //该商品状态已通过审核
        wrapper.eq("status", 1);
        //商品库存大于0
        wrapper.gt("stock_count", 0);
        //TODO 取出该天日期的商品
        wrapper.eq("DATE_FORMAT(start_time,'%Y-%m-%d')", DateUtil.formatDate(new Date()));
        List<SeckillProduct> seckillProductList = seckillProductService.list(wrapper);
        if (!CollectionUtils.isEmpty(seckillProductList)){
            for (SeckillProduct seckillProduct : seckillProductList) {
                boolean flag = redisTemplate.boundHashOps(RedisConst.SECKILL_PRODUCT).hasKey(seckillProduct.getSkuId().toString());
                if (flag){
                    continue;
                }
                //把秒杀放redis
                redisTemplate.boundHashOps(RedisConst.SECKILL_PRODUCT).put(seckillProduct.getSkuId().toString(), seckillProduct);
                //利用list集合的数据结构存储剩余商品数量,减库存的时候list取一个防止超卖
                for (Integer integer = 0; integer < seckillProduct.getNum(); integer++) {
                    redisTemplate.boundListOps(RedisConst.SECKILL_STOCK_PREFIX+seckillProduct.getSkuId())
                            .leftPush(seckillProduct.getSkuId().toString());
                }
                //TODO 5.通知redis集群中其他节点该商品可以进行秒杀了 状态位
                redisTemplate.convertAndSend(RedisConst.PREPARE_PUB_SUB_SECKILL,
                        seckillProduct.getSkuId()+":"+RedisConst.CAN_SECKILL);
            }
        }
        // 手动确认k
            channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);
        }


    //2.预下单的监听器
    @RabbitListener(bindings = @QueueBinding(
            value = @Queue(value = MqConst.PREPARE_SECKILL_QUEUE,durable = "false"),
            exchange = @Exchange(value = MqConst.PREPARE_SECKILL_EXCHANGE,durable = "false"),
            key = {MqConst.PREPARE_SECKILL_ROUTE_KEY}))
    public void prepareSeckill(UserSeckillSkuInfo userSeckillSkuInfo, Message message, Channel channel) throws IOException {
        if(userSeckillSkuInfo!=null){
            //开始处理预下单
            seckillProductService.propareSeckil(userSeckillSkuInfo);
        }
        channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);
    }
    }














